package services;

import domain.entities.*;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.*;

/**
 * Created with IntelliJ IDEA.
 * User: scamisay
 * Date: 10/26/12
 * Time: 5:25 PM
 * To change this template use File | Settings | File Templates.
 */
@Service
public class ProtocoloCentroService {
    private ProtocoloCentroDAO dao;
    private CentroCRUDService centroCentroCRUDService;
    private EthicsCommitteeCRUDService ethicsCommitteeCRUDService;

    public ProtocoloCentroService(){
    }

    @Autowired
    public ProtocoloCentroService(ProtocoloCentroDAO dao,CentroCRUDService centroCentroCRUDService,
                                  EthicsCommitteeCRUDService ethicsCommitteeCRUDService) {
        this.dao = dao;
        this.centroCentroCRUDService = centroCentroCRUDService;
        this.ethicsCommitteeCRUDService = ethicsCommitteeCRUDService;
    }

    public List<ProtocoloCentro> findAllByProtocoloCompromisopais(ProtocoloCompromisopais protocoloCompromisopais){
        List<ProtocoloCentro> list = dao.findAll();
        Iterator<ProtocoloCentro> it = list.iterator();
        while(it.hasNext()){
            ProtocoloCompromisopais pIt = it.next().getProtocoloCompromisopais();
            ProtocoloCompromisopaisId idIt = pIt.getId();
            if(!idIt.getProtocoloid().equals(protocoloCompromisopais.getId().getProtocoloid())
                    ||
                    !idIt.getCompromisopaisid().equals(protocoloCompromisopais.getId().getCompromisopaisid())
                    ){
                it.remove();
            }
        }
        return list;
    }

    public ProtocoloCentro findById(ProtocoloCentroId protocoloCentroId){
        return dao.findById(protocoloCentroId);
    }

    /*Ya viene con el protocolo compromiso pais seteado*/
    public void save(ProtocoloCentro protocoloCentro) {
        //Recupero el centro
        Integer centroId = protocoloCentro.getCentro().getId();
        Centro centro = centroCentroCRUDService.findById(centroId);
        if(centro.getStatus() == null || centro.getStatus().trim().isEmpty())
            centro.setStatus("Under Selection Process");
        protocoloCentro.setCentro(centro);

        /*creo el id*/
        ProtocoloCompromisopais protocoloCompromisopais = protocoloCentro.getProtocoloCompromisopais();
        ProtocoloCentroId protocoloCentroId = new ProtocoloCentroId();
        protocoloCentroId.setCentroid(centro.getId());
        protocoloCentroId.setProtocoloCompromisopaiscompromisopaisid(
                protocoloCompromisopais.getId().getCompromisopaisid()
        );
        protocoloCentroId.setProtocoloCompromisopaisprotocoloid(
                protocoloCompromisopais.getId().getProtocoloid()
        );

        protocoloCentro.setId(protocoloCentroId);
        protocoloCentro.setProtocoloCentroprotocoloid(
                protocoloCompromisopais.getId().getProtocoloid()
        );
        protocoloCentro.setProtocoloCentrocentroid(
                protocoloCompromisopais.getId().getCompromisopaisid()
        );

        protocoloCentro.setComiteEticas(cargarComitesEtica(protocoloCentro));


//        ProtocoloCentro persisted = null;
//        if(protocoloCentro.getId()!=null){
//            persisted = dao.findById(protocoloCentro.getId());
//
//        }
//        protocoloCentro.getComiteEticas().remove(persisted.getComiteEticas());
//        ComiteEtica persisted = null;
//        if(comiteEtica.getId() != null){
//            persisted = dao.findById(comiteEtica.getId());
//            for(ContactPerson cp : persisted.getContactPersons()){
//                contactPersondDAO.delete(cp);
//            }
//        }
//        ArrayList<ContactPerson> cps = new ArrayList<ContactPerson>(0);
//        for(ContactPerson cp : comiteEtica.getContactPersons()){
//            if(cp == null)
//                cps.add(cp);
//            else
//                cp.setComiteEtica(comiteEtica);
//        }
//
//        comiteEtica.getContactPersons().removeAll(cps);
//



        /*guardar protocolo centro*/
        dao.merge(protocoloCentro);

    }

    private  Set<ComiteEtica> cargarComitesEtica(ProtocoloCentro pc) {
        Collection<ComiteEtica> comites = pc.getComiteEticas();
        Set<ComiteEtica> comitesConvertidos = new HashSet<ComiteEtica>();
        Iterator<ComiteEtica> it = comites.iterator();
        while( it.hasNext() ){
            ComiteEtica actual = it.next();
            if(actual != null && actual.getId() != null){
                int id = actual.getId();

                ComiteEtica ce = ethicsCommitteeCRUDService.findById(id);
                comitesConvertidos.add(ce);
            }
        }
        return comitesConvertidos;
    }

    private ProtocoloCentro createProtocoloCentro(ProtocoloCompromisopais protocoloCompromisopais,
                                                  Centro centro,
                                                  Set<ComiteEtica> comites){
        //Armo protocolo centro
        ProtocoloCentro protocoloCentro = new ProtocoloCentro();
        protocoloCentro.setCentro(centro);
//        protocoloCentro.setProtocoloCompromisopais(protocoloCompromisopais);

        ProtocoloCentroId protocoloCentroId = new ProtocoloCentroId();
        protocoloCentroId.setCentroid(centro.getId());
        protocoloCentroId.setProtocoloCompromisopaiscompromisopaisid(
                protocoloCompromisopais.getId().getCompromisopaisid()
        );
        protocoloCentroId.setProtocoloCompromisopaisprotocoloid(
                protocoloCompromisopais.getId().getProtocoloid()
        );

//        protocoloCentro.setId(protocoloCentroId);
        protocoloCentro.setProtocoloCentroprotocoloid(
                protocoloCompromisopais.getId().getProtocoloid()
        );
        protocoloCentro.setProtocoloCentrocentroid(
                protocoloCompromisopais.getId().getCompromisopaisid()
        );

        protocoloCentro.setComiteEticas(comites);

        /*guardar protocolo centro*/
        dao.attachDirty(protocoloCentro);

        return protocoloCentro;
    }

    public List<Centro> getSitesByProtocoloCompromisoPaisAndIPCs(ProtocoloCompromisopais pcp,
                                                          List<InvestigadorProtocoloCentro> ipcs) {
        Set<Centro> ocupados = new HashSet<Centro>();
        for(InvestigadorProtocoloCentro ipc : ipcs){
            ocupados.add(ipc.getProtocoloCentro().getCentro());
        }

        return getSitesAvailablesByProtocoloCompromisoPais(pcp,ocupados);
    }

    public List<Centro> getSitesByProtocoloCompromisoPaisAndLocalVendors(ProtocoloCompromisopais pcp,
                                                          List<Vendorcentral> localVendors) {
        Set<Centro> ocupados = new HashSet<Centro>();
        for(Vendorcentral v : localVendors){
            for(Centro s : v.getSites()){
                ocupados.add(s);
            }
        }

        return getSitesAvailablesByProtocoloCompromisoPais(pcp,ocupados);
    }

    private List<Centro> getSitesAvailablesByProtocoloCompromisoPais(ProtocoloCompromisopais pcp, Set<Centro> ocupados){
        List<ProtocoloCentro> list = findAllByProtocoloCompromisopais(pcp);
        List<Centro> centros = new ArrayList<Centro>();
        for(ProtocoloCentro pc : list){
            if(!ocupados.contains(pc.getCentro())){
                centros.add(pc.getCentro());
            }
        }
        return centros;
    }
}
